import { initState } from "./state";
import { compileToFunction } from "./complier/index";
import { mountComponent, callHook } from "./lifecycle";
import { mergeOptions } from "./utils/index";
import { nextTick } from "./utils/index";

// 在原型上添加init方法
export function initMixin(Vue) {
	// 初始化流程
	Vue.prototype._init = function (options) {
		// 数据劫持,让数据变成响应式的
		const vm = this;
		// 将用户传递的属性跟全局的属性合并,通过当前实例的构造器拿到当前的属性
		vm.$options = mergeOptions(vm.constructor.options, options);
		// 调用创建前的hook
		callHook(vm, "beforeCreate");
		// 初始化状态
		initState(vm);
		// 调用初始化好数据时的hook
		callHook(vm, "create");
		// 判断传来el参数没有
		const { el } = vm.$options;
		// 有就进行挂载
		if (el) {
			vm.$mount(el);
		}
	};

	// 给原型挂上挂载$mount方法
	Vue.prototype.$mount = function (el) {
		const vm = this;
		// 解构属性
		let { render, template } = vm.$options;
		// 获取真实dom挂载点
		el = document.querySelector(el);
		// 默认会先找render方法,然后找template,最后才是el中的内容
		// 没有render
		if (!render) {
			// 对模板进行编译
			// 没有template并且有el,解析el中的内容
			if (!template && el) {
				template = el.outerHTML;
			}
			// 编译模板,并且把render方法挂载到当前实例上 template -> render
			render = vm.$options.render = compileToFunction(template);
		}
		// 渲染页面
		mountComponent(vm, el);
	};

	// 给原型挂上$nextTick方法
	Vue.prototype.$nextTick = nextTick;
}
